﻿using System;
using System.IO;
using System.IO.Compression;
using System.Text;
using System.Windows.Forms;
using System.Windows.Media.Imaging;

namespace Epicor.Pub
{
    /// <summary>文件操作类</summary>
    public class PubFile
    {
        /// <summary> 删除文件 </summary>
        public static bool DeleteFile(string FileFullPath)
        {
            if (File.Exists(FileFullPath) == true) //用判断文件是否存在
            {
                File.SetAttributes(FileFullPath, FileAttributes.Normal); //设置文件的属性为正常（如果文件为只读的话直接删除会报错）
                File.Delete(FileFullPath); //删除文件
                return true;
            }
            else //文件不存在
            {
                return false;
            }
        }

        /// <summary>获取文件文件扩展名</summary>
        public static string GetFileExtension(string FileFullPath)
        {
            if (File.Exists(FileFullPath) == true)
            {
                FileInfo F = new FileInfo(FileFullPath);
                return F.Extension; //获取文件扩展名（包含".",如：".mp3"）
            }
            else
            {
                return null;
            }
        }

        /// <summary>获取文件名（是否包含扩展名）</summary>
        public static string GetFileName(string FileFullPath, bool IncludeExtension=true)
        {
            if (File.Exists(FileFullPath) == true)
            {
                FileInfo F = new FileInfo(FileFullPath);
                if (IncludeExtension)
                {
                    return F.Name;   //返回文件名（包含扩展名）
                }
                else
                {
                    return F.Name.Replace(F.Extension, ""); //把扩展名替换为空字符
                }
            }
            else
            {
                return null;
            }
        }

        /// <summary>外部打开文件，用系统注册类型关联软件打开</summary>
        public static bool OpenFile(string FileFullPath)
        {
            if (File.Exists(FileFullPath) == true)
            {
                System.Diagnostics.Process.Start(FileFullPath);
                return true;
            }
            else
            {
                return false;
            }
        }

        /// <summary>获取文件大小</summary>
        public static string GetFileSize(string FileFullPath)
        {
            if (File.Exists(FileFullPath) == true)
            {
                FileInfo F = new FileInfo(FileFullPath);
                long FL = F.Length;
                if (FL > (1024 * 1024 * 1024)) //由大向小来判断文件的大小
                {
                    return Math.Round((FL + 0.00) / (1024 * 1024 * 1024), 2).ToString() + " GB"; //将双精度浮点数舍入到指定的小数（long类型与double类型运算，结果会是一个double类型）
                }
                else if (FL > (1024 * 1024))
                {
                    return Math.Round((FL + 0.00) / (1024 * 1024), 2).ToString() + " MB";
                }
                else if (FL > 1024)
                {
                    return Math.Round((FL + 0.00) / 1024, 2).ToString() + " KB";
                }
                else
                {
                    return FL.ToString();
                }
            }
            else
            {
                return null;
            }
        }

        /// <summary>文件转换成二进制，返回二进制数组Byte[] </summary>
        public static byte[] FileToStreamByte(string FileFullPath)
        {
            if (File.Exists(FileFullPath) == true)
            {
                FileStream FS = new FileStream(FileFullPath, FileMode.Open); //创建一个文件流
                byte[] fileData = new byte[FS.Length];                       //创建一个字节数组，用于保存流
                FS.Read(fileData, 0, fileData.Length);                       //从流中读取字节块，保存到缓存中
                FS.Close();                                                  //关闭流（一定得关闭，否则流一直存在）
                return fileData;                                             //返回字节数组
            }
            else
            {
                return null;
            }
        }

        /// <summary> 二进制数组Byte[]生成文件</summary>
        public static bool ByteStreamToFile(string FileFullPath, byte[] StreamByte)
        {
            try
            {
                if (File.Exists(FileFullPath)) 
                {
                    DeleteFile(FileFullPath);
                }
                FileStream FS = new FileStream(FileFullPath, FileMode.OpenOrCreate); //创建文件流(打开或创建的方式)
                FS.Write(StreamByte, 0, StreamByte.Length); //把文件流写到文件中
                FS.Close();
                return true;
            }
            catch
            {
                return false;
            }
        }

        /// <summary> 写文件 </summary>
        public static void WriteFile(string FileFullPath, string Strings,string encode= "gb2312")
        {
            if (!File.Exists(FileFullPath))
            {
                FileStream fs = File.Create(FileFullPath);
                fs.Close();
            }
            StreamWriter sw = new StreamWriter(FileFullPath, false, Encoding.GetEncoding(encode));
            sw.Write(Strings);
            sw.Flush();
            sw.Close();
            sw.Dispose();
        }
        /// <summary>读文件</summary>
        public static string ReadFile(string FileFullPath, string encode = "gb2312")
        {
            
            string stemp = "";
            if (!File.Exists(FileFullPath))throw new Exception("文件不存在!");
            else
            {
                StreamReader fr = new StreamReader(FileFullPath, Encoding.GetEncoding(encode));
                stemp = fr.ReadToEnd();
                fr.Close();
                fr.Dispose();
            }

            return stemp;
        }

        /// <summary> 追加文本</summary>
        public static void FileAdd(string FileFullPath, string strings)
        {
            StreamWriter sw = File.AppendText(FileFullPath);
            sw.Write(strings);
            sw.Flush();
            sw.Close();
        }

        /// <summary>将Xml文件序列化(可起到加密和压缩XML文件的目的)</summary>
        public static bool SerializeXml(string FileFullPath)  
        {
            try
            {
                System.Data.DataSet DS = new System.Data.DataSet(); //创建数据集，用来临时存储XML文件
                DS.ReadXml(FileFullPath); //将XML文件读入到数据集中
                FileStream FS = new FileStream(FileFullPath + ".tmp", FileMode.OpenOrCreate); //创建一个.tmp的临时文件
                System.Runtime.Serialization.Formatters.Binary.BinaryFormatter FT = new System.Runtime.Serialization.Formatters.Binary.BinaryFormatter(); //使用二进制格式化程序进行序列化
                FT.Serialize(FS, DS); //把数据集序列化后存入文件中
                FS.Close(); //一定要关闭文件流，否则文件改名会报错（文件正在使用错误）
                DeleteFile(FileFullPath); //删除原XML文件
                File.Move(FileFullPath + ".tmp", FileFullPath); //改名(把临时文件名改成原来的xml文件名)
                return true;
            }
            catch
            {
                return false;
            }
        }

        /// <summary> 反序列化XML文件</summary>
        public static bool DeSerializeXml(string FileFullPath)
        {
            FileStream FS = new FileStream(FileFullPath, FileMode.Open); //打开XML文件流

            System.Runtime.Serialization.Formatters.Binary.BinaryFormatter FT = new System.Runtime.Serialization.Formatters.Binary.BinaryFormatter(); //使用二进制格式化程序进行序列化
            ((System.Data.DataSet)FT.Deserialize(FS)).WriteXml(FileFullPath + ".tmp"); //把文件反序列化后存入.tmp临时文件中
            FS.Close(); //关闭并释放流
            DeleteFile(FileFullPath); //删除原文件
            File.Move(FileFullPath + ".tmp", FileFullPath); //改名(把临时文件改成原来的xml文件)
            return true;
        }
        /// <summary>压缩文件 </summary>
        public static void CompressFile(string sourceFile, string destinationFile)
        {
            // 文件是否存在
            if (File.Exists(sourceFile) == false)throw new FileNotFoundException();
            byte[] buffer = null;
            FileStream sourceStream = null;
            FileStream destinationStream = null;
            GZipStream compressedStream = null;
            try
            {
                // 读取源文件到byte数组
                sourceStream = new FileStream(sourceFile, FileMode.Open, FileAccess.Read, FileShare.Read);
                buffer = new byte[sourceStream.Length];
                int checkCounter = sourceStream.Read(buffer, 0, buffer.Length);
                if (checkCounter != buffer.Length)
                {
                    throw new ApplicationException();
                }
                destinationStream = new FileStream(destinationFile, FileMode.OpenOrCreate, FileAccess.Write);
                compressedStream = new GZipStream(destinationStream, CompressionMode.Compress, true);
                compressedStream.Write(buffer, 0, buffer.Length);
            }
            catch (ApplicationException ex)
            {
                throw (ex);
            }
            finally
            {
                if (sourceStream != null) sourceStream.Close();
                if (compressedStream != null)compressedStream.Close();
                if (destinationStream != null) destinationStream.Close();
            }
        }

        /// <summary>解压文件</summary>
        public static void DeCompressFile(string sourceFile, string destinationFile)
        {
            if (File.Exists(sourceFile) == false)throw new FileNotFoundException();
            FileStream sourceStream = null;
            FileStream destinationStream = null;
            GZipStream decompressedStream = null;
            byte[] quartetBuffer = null;

            try
            {
                sourceStream = new FileStream(sourceFile, FileMode.Open);
                decompressedStream = new GZipStream(sourceStream, CompressionMode.Decompress, true);
                quartetBuffer = new byte[4];
                int position = (int)sourceStream.Length - 4;
                sourceStream.Position = position;
                sourceStream.Read(quartetBuffer, 0, 4);
                sourceStream.Position = 0;
                int checkLength = BitConverter.ToInt32(quartetBuffer, 0);
                byte[] buffer = new byte[checkLength + 100];
                int offset = 0;
                int total = 0;
                while (true)
                {
                    int bytesRead = decompressedStream.Read(buffer, offset, 100);
                    if (bytesRead == 0) break;
                    offset += bytesRead;
                    total += bytesRead;
                }

                destinationStream = new FileStream(destinationFile, FileMode.Create);
                destinationStream.Write(buffer, 0, total);
                destinationStream.Flush();
            }
            catch (ApplicationException ex)
            {
                throw (ex);
            }
            finally
            {
                if (sourceStream != null) sourceStream.Close();
                if (decompressedStream != null)decompressedStream.Close();
                if (destinationStream != null)destinationStream.Close();
            }

        }
        /// <summary> 保存为Jpg图片 </summary>
        static public bool SaveImage2Jpg(BitmapSource bsrc, int quality = -1)
        {
            bool ret = false;

            if (null != bsrc)
            {
                SaveFileDialog sf = new SaveFileDialog();
                sf.FileName = "未命名";
                sf.DefaultExt = ".jpg";
                sf.Filter = "jpg (.jpg)|*.jpg";

                if (DialogResult.OK == sf.ShowDialog())
                {
                    JpegBitmapEncoder encoder = new JpegBitmapEncoder();
                    encoder.Frames.Add(BitmapFrame.Create(bsrc));
                    using (Stream stream = File.Create(sf.FileName))
                    {
                        if (quality >= 0 && quality <= 100)
                        {
                            encoder.QualityLevel = quality;
                        }
                        else
                        {
                            encoder.QualityLevel = 80;
                        }
                        try
                        {
                            encoder.Save(stream);
                            ret = true;
                        }
                        catch
                        {

                        }
                    }
                }
            }

            return ret;
        }
        /// <summary>图片加载</summary>
        static public BitmapImage LoadImages(string filepath, int dpWidth)
        {
            BitmapImage bitmap = new BitmapImage();
            MemoryStream ms = null;
            using (BinaryReader binReader = new BinaryReader(File.Open(filepath, FileMode.Open, FileAccess.Read, FileShare.Read)))
            {
                try
                {
                    FileInfo fileInfo = new FileInfo(filepath);
                    byte[] bytes = binReader.ReadBytes((int)fileInfo.Length);

                    bitmap.BeginInit();
                    bitmap.CacheOption = BitmapCacheOption.OnLoad;
                    ms = new MemoryStream(bytes);
                    bitmap.StreamSource = ms;
                    bitmap.DecodePixelWidth = dpWidth;
                    bitmap.EndInit();
                    bitmap.Freeze();
                }
                catch (Exception ep)
                {
                    MessageBox.Show(ep.Message);
                }
                finally
                {
                    if (null != ms)
                    {
                        ms.Dispose();
                        ms = null;
                    }
                    binReader.Close();
                    GC.Collect();
                }
            }
            return bitmap;
        }
        /// <summary>写日志文件</summary>
        public static void Log(string filepath, string msg)
        {
            DateTime dt = System.DateTime.Now;
            msg += "\r\n时间:" + dt.ToString() + " " + dt.Millisecond.ToString() + "------>";
            FileStream fs = new FileStream(filepath, FileMode.Append);
            try
            {
                byte[] data = new System.Text.UTF8Encoding().GetBytes(msg); //获得字节数组
                fs.Write(data, 0, data.Length);//开始写入
                fs.Flush();  //清空缓冲区、关闭流
            }
            catch (System.Exception ex)
            {
                Console.WriteLine(ex.Message);
            }
            finally
            {
                if (null != fs)
                {
                    fs.Close();
                    fs.Dispose();
                }
            }
        }
        /// <summary>文件拷贝(可覆盖）</summary>
        public static bool FileCopy(string sourceFile, string destFile)
        {
            bool ret = false;

            if (File.Exists(sourceFile))
            {
                try
                {
                    if (File.Exists(destFile))
                    {
                        DeleteFile(destFile);
                    }
                    File.Copy(sourceFile, destFile);
                    ret = true;
                }
                catch (Exception ex)
                {
                    MessageBox.Show(ex.Message);
                }
            }
            return ret;
        }
    }
}
